home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 90 / CD Actual 90.iso / Software3D / K-3D / k3d-0.4.2.1 / shaders / k3d_smoke2.sl < prev    next >
Encoding:
Text File  |  2004-07-23  |  5.6 KB  |  158 lines

  1. /**************************************************************************
  2.  * TLSmoke.sl -- This is really Larry's noisysmoke.sl.  I only took out the
  3.  * random() as it made my animation look to funky -- tal 9/4/96
  4.  *
  5.  * Description:
  6.  *    This is a volume shader for smoke.  Trapezoidal integration is
  7.  *    used to integrate the GADD to find scattering and extinction.
  8.  *
  9.  * Parameters:
  10.  *   density - overall smoke density control
  11.  *   integstart, integend - bounds along the viewing ray direction of the
  12.  *          integration of atmospheric effects.
  13.  *   stepsize - step size for integration
  14.  *   use_lighting - if nonzero, light visibility along the ray will be taken
  15.  *          into account.
  16.  *   use_noise - makes the smoke noisy (nonuniform) when nonzero
  17.  *   freq, octaves, smokevary - control the fBm of the noisy smoke
  18.  *   lightscale - multiplier for light scattered toward viewer in volume
  19.  *   debug - if nonzero, copious output will be sent to stderr.
  20.  *
  21.  * Author: Larry Gritz
  22.  *
  23.  * History:
  24.  *   9/4/96 tal -- took out random call and renamed to TLSmoke
  25.  *
  26.  * $Revision: 1.1 $     $Date: 2003/02/11 14:32:43 $
  27.  *
  28.  * $Log: k3d_smoke2.sl,v $
  29.  * Revision 1.1  2003/02/11 14:32:43  blackburst
  30.  * * Initial checkin
  31.  *
  32.  * Revision 1.3  1996-03-01 17:07:40-08  lg
  33.  * Eliminated duplicate local variable declarations
  34.  *
  35.  * Revision 1.2  1996-02-29 18:04:26-08  lg
  36.  * Compute only one octave of noise when not lit (big speedup)
  37.  *
  38.  * Revision 1.1  1996-02-05 11:03:45-08  lg
  39.  * Initial RCS revision
  40.  *
  41.  **************************************************************************/
  42.  
  43.  
  44. #define snoise(p) (2*noise(p)-1)
  45.  
  46.  
  47. /* Here is where we define the GADD. */
  48. #define GADD(PP,PW,li,g)                                                    \
  49.          if (use_lighting > 0) {                                            \
  50.          li = 0;                                                        \
  51.          illuminance (PW, point(0,0,1), PI) { li += Cl; }               \
  52.      } else { li = 1; }                                                 \
  53.          if (use_noise != 0) {                                              \
  54.              Psmoke = PP*freq;                                              \
  55.              smoke = snoise (Psmoke);                                       \
  56.              /* Optimize: one octave only if not lit */                     \
  57.          if (comp(li,0)+comp(li,1)+comp(li,2) > 0.01) {                 \
  58.                  f=1;                                                       \
  59.                  for (i=1;  i<octaves;  i+=1) {                             \
  60.                       f *= 0.5;  Psmoke *= 2;                               \
  61.                       smoke += f*snoise(Psmoke);                            \
  62.                  }                                                          \
  63.              }                                                              \
  64.              g = density * smoothstep(-1,1,smokevary*smoke);                \
  65.          } else g = density;                                                \
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. volume
  74. k3d_smoke2 (float density = 60;
  75.         float integstart = 0, integend = 100;
  76.         float stepsize = 0.1;
  77.         float debug = 0;
  78.         float use_lighting = 1;
  79.         float use_noise = 1;
  80.         color scatter = 1;   /* for sky, try (1, 2.25, 21) */
  81.         float octaves = 3, freq = 1, smokevary = 1;
  82.         float lightscale = 15;
  83.         )
  84. {
  85. #ifdef BMRT
  86.   point Worigin = P + I;
  87.   point incident = vtransform ("shader", -I);
  88. #else  /* PRMan and BMRT have I reverse of each other, conflict in spec */
  89.   point Worigin = P - I;
  90.   point incident = vtransform ("shader", I);
  91. #endif
  92.   point origin = transform ("shader", Worigin);
  93.   point IN, WIN;
  94.   float d, sigma, tau;
  95.   color Cv = 0, Ov = 0;           /* net color & opacity of volume */
  96.   color dC, dO;                   /* differential color & opacity */
  97.   float ss, dtau, last_dtau, end;
  98.   float nsteps = 0;          /* record number of integration steps */
  99.   color li, last_li, lighttau;
  100.   point PP, PW, Psmoke;
  101.   color scat;
  102.   float f, i, smoke;
  103.  
  104.   end = min (length (incident), integend) - 0.0001;
  105.  
  106.   /* Integrate forwards from the start point */
  107.   d = integstart + /*random()* */ stepsize;
  108.   if (d < end) {
  109.       IN = normalize (incident);
  110.       WIN = vtransform ("shader", "current", IN);
  111.       PP = origin + d * IN;
  112.       PW = Worigin + d * WIN;
  113.       GADD (PP, PW, li, dtau)
  114.       ss = min (stepsize, end-d);
  115.       d += ss;
  116.       nsteps += 1;
  117.  
  118.       while (d <= end) {
  119.       last_dtau = dtau;
  120.       last_li = li;
  121.       PP = origin + d*IN;
  122.       PW = Worigin + d*WIN;
  123.       GADD (PP, PW, li, dtau)
  124.       /* Our goal now is to find dC and dO, the color and opacity
  125.        * of the portion of the volume covered by this step.
  126.        */
  127.       tau = .5 * ss * (dtau + last_dtau);
  128.       lighttau = .5 * ss * (li*dtau + last_li*last_dtau);
  129.  
  130.       scat = -tau * scatter;
  131.       dO = 1 - color (exp(comp(scat,0)), exp(comp(scat,1)), exp(comp(scat,2)));
  132.       dC = lighttau * dO;
  133.  
  134.       /* Now we adjust Cv/Ov to account for dC and dO */
  135.       Cv += (1-Ov)*dC;
  136.       Ov += (1-Ov)*dO;
  137.  
  138.       ss = max (min (ss, end-d), 0.005);
  139.       d += ss;
  140.       nsteps += 1;
  141.         }
  142.     }
  143.  
  144.   /* Ci & Oi are the color (premultiplied by opacity) and opacity of 
  145.    * the background element.
  146.    * Now Cv is the light contributed by the volume itself, and Ov is the
  147.    * opacity of the volume, i.e. (1-Ov)*Ci is the light from the background
  148.    * which makes it through the volume.
  149.    */
  150.   Ci = lightscale*Cv + (1-Ov)*Ci; 
  151.   Oi = Ov + (1-Ov)*Oi;
  152.   
  153.   if (debug > 0) {
  154.       printf ("nsteps = %f, t1 = %f, end = %f\n", nsteps, integstart, end);
  155.       printf ("   Cv = %c, Ov = %c\n", Cv, Ov);
  156.     }
  157. }
  158.